require "redis"
require "open3"
require "fileutils"
require "digest"
require "active_support/all"
# require_relative "price_protect/core_ext/blank"
require_relative "price_protect/version"
require_relative "price_protect/configuration"
require_relative "price_protect/storeage/upyun"

module PriceProtect

  SECURITY_CONTENT = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'].freeze
  REDIS_NUMBER_LIST_KEY = 'price-protect-list'.freeze

  class << self
    # 考虑单个随机shuffle
    def generate_number_sequence
      _postfix = SECURITY_CONTENT[(PriceProtect.config.security_level+1)..-1].join('')
      FileUtils.mkdir_p(PriceProtect.config.image_store_path) unless File.exist?(PriceProtect.config.image_store_path)
      SECURITY_CONTENT[0..PriceProtect.config.security_level].permutation.to_a.each do |rand_content|
        _content = "#{rand_content.join('')}#{_postfix}"
        _filepath = generate_file_path(_content)
        next if File.exist?(_filepath)
        create(_content, _filepath)
      end
      # store image
      store_image
    end

    def generate_file_path content
      "#{PriceProtect.config.image_store_path}/#{Digest::MD5.hexdigest(content)}.png"
    end

    def redis_client
      # @redis ||= Redis.new(driver: :hiredis)
      @redis ||= Redis.new()
    end

    def create(content, filepath)
      # 右边空白10px, 字宽度8px, 样式计算10的8递增
      command = <<-CODE
        convert -size 108x20 \
        xc:transparent \
        -pointsize 14 \
        -fill '#b85858' \
        -draw "text 20,14 \'#{content}\'" #{filepath}
      CODE
      # excute command
      command.strip!
      _out, _err, _st = Open3.capture3(command)
      puts "PriceProtect #{_err.strip}" unless _err.blank?
      puts "create #{filepath}"
      # store number
      store_number(content)
      _out
    end

    def store_number(content)
      redis_client.sadd(REDIS_NUMBER_LIST_KEY, content)
    end

    def store_image
      if PriceProtect.config.is_upyun_storeage?
        PriceProtect::Storeage::Upyun.publish(bucket: PriceProtect.config.upyun_bucket, username: PriceProtect.config.upyun_username, password: PriceProtect.config.upyun_password, localpath: PriceProtect.config.image_store_path)
      end
    end

  end # end self

  class Service
    attr_accessor :number_string, :number_array, :file_name

    def initialize(number=nil)
      extract(number)
    end

    def extract(number)
      @number_string = number if number.present?
      @number_string ||= redis_client.srandmember(REDIS_NUMBER_LIST_KEY)
      @number_array = @number_string.split('')
      @file_name ||= "#{Digest::MD5.hexdigest(number_string)}.png"
    end

    def redis_client
      PriceProtect.redis_client
    end

    def image_path
      if PriceProtect.config.is_upyun_storeage?
        "#{PriceProtect.config.upyun_host}/#{@file_name}"
      else
        "#{PriceProtect.config.image_store_path}/#{@file_name}"
      end
    end

    # 把价格转化成对应图片下标数组
    def encode_price price
      price.to_s.chars.map { |char| @number_array.index(char) }
    end

    def encode_price_to_css price
      price.to_s.chars.map { |char| "p29_0_#{@number_array.index(char)}" }
    end

    def css_style
      %{
        var {
          background-repeat: no-repeat;
        }
        .p29_0_0,.p29_0_1,.p29_0_2,.p29_0_3,.p29_0_4,.p29_0_5,.p29_0_6,.p29_0_7,.p29_0_8,.p29_0_9,.p29_0_10 {
          background-image: url(#{image_path}); font-size: 14px
        }
        .p29_0_0{ background-position: -19px -1px; padding: 0 4px }
        .p29_0_1{ background-position: -27px -1px; padding: 0 4px }
        .p29_0_2{ background-position: -35px -1px; padding: 0 4px }
        .p29_0_3{ background-position: -43px -1px; padding: 0 4px }
        .p29_0_4{ background-position: -51px -1px; padding: 0 4px }
        .p29_0_5{ background-position: -59px -1px; padding: 0 4px }
        .p29_0_6{ background-position: -67px -1px; padding: 0 4px }
        .p29_0_7{ background-position: -75px -1px; padding: 0 4px }
        .p29_0_8{ background-position: -83px -1px; padding: 0 4px }
        .p29_0_9{ background-position: -91px -1px; padding: 0 4px }
        .p29_0_10{ background-position: -99px -1px; padding: 0 4px }
      }
    end
  end # end service

end
